package com.service;

import static com.def.GenericDef.E_XPINQLOT_OTHER_ERROR;
import static com.def.GenericDef.PATH_TYPE_REWK;
import static com.def.GenericDef.PROC_WAIT;
import static com.def.GenericDef.RETURN_CODE_OK;
import static com.def.GenericDef.RETURN_MESG_OK;
import static com.def.GenericDef._NO;
import static com.def.GenericDef._NORMAL;
import static com.def.GenericDef._YES;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import com.dao.IRetPrdInfoDao;
import com.dao.IRetWODao;
import com.icim.service.ICIMBaseService;
import com.mapKeyVal.key.StatBoxOpeBnkWoKey;
import com.mapKeyVal.key.WoGradeKey;
import com.dao.IBisPathiDao;
import com.model.Bis_pathi;
import com.model.Bis_pathiId;
import com.model.Ret_prd_info;
import com.model.Ret_wo;
import com.tx.Xpinqlot.XpinqlotOA;
import com.tx.Xpinqsor.XpinqsorI;
import com.tx.Xpinqsor.XpinqsorO;
import com.tx.Xpinqsor.XpinqsorO1;
import com.tx.Xpinqsor.XpinqsorO2;
import com.tx.Xpinqsor.XpinqsorO3;
import com.util.MqOpe;
import com.util.Util;

@Scope("prototype")
@Service("XpinqsorService")
public class XpinqsorService extends ICIMBaseService{
	private Logger logger = Logger.getLogger(XpinqsorService.class);
	@Autowired
	private XpinqsorI inTrx;
	@Autowired
	private XpinqsorO outTrx;

	@Autowired
	private IRetWODao retWODao;
	
	@Autowired
	private IBisPathiDao bisPathiDao;

	@Autowired
	private IRetPrdInfoDao retPrdInfoDao;

	private String gszMsgBuf = "";

	private MqOpe mqOpe;
	
	static String hql;

	public String subMainProc(String strInMsg) {
		mqOpe = new MqOpe();

		inTrx = (XpinqsorI) mqOpe.inStr2Obj(strInMsg, inTrx);
		char action_flgAry[] = inTrx.getAction_flg().toCharArray();
		char action_flg = action_flgAry[0];
		switch (action_flg) {
		case 'M':
			summaryWoInfoFor9800();
			break;
		case 'L':
			getPrdListInfo();
			break;
		default:
			logger.info("mapping no action_flg ,error");
		}
		logger.info(mqOpe.obj2Str(outTrx));
		return mqOpe.obj2Str(outTrx);
	}
    private void getPrdListInfo(){
		List<Ret_prd_info> retPrdInfoList = null;
		List<XpinqsorO3> oaryList = new ArrayList<XpinqsorO3>();
		
			String hql = " FROM Ret_prd_info where so_id_fk=:so_id_fk";
			try {
				Query query = retPrdInfoDao.getCrSession().createQuery(hql);
				query.setString("so_id_fk", inTrx.getSo_id());
				retPrdInfoList = query.list();
			} catch (Exception ex) {
				logger.error("read RET_PRD_INFO ERROR:" + ex.getMessage());
				logger.error(Util.stackTraceToString(ex));
			}

		for (Ret_prd_info ret_prd_info : retPrdInfoList) {
			XpinqsorO3 oary = new XpinqsorO3();
			oary.setPrd_seq_id(ret_prd_info.getPrd_seq_id());
			oary.setFab_sn(ret_prd_info.getFab_sn());
			oary.setSlot_no(ret_prd_info.getSlot_no());
			oary.setPrd_stat(ret_prd_info.getPrd_stat());
			oary.setBox_id_fk(ret_prd_info.getBox_id_fk());
			oary.setPrd_grade(ret_prd_info.getPrd_grade());
			String pathId = PROC_WAIT.equals(ret_prd_info.getPrd_stat()) ? ret_prd_info.getNx_path_id_fk() : ret_prd_info.getCr_path_id_fk();
			String pathVer = PROC_WAIT.equals(ret_prd_info.getPrd_stat()) ? ret_prd_info.getNx_path_ver_fk() : ret_prd_info.getCr_path_ver_fk();
			Bis_pathiId id = new Bis_pathiId();
			id.setPath_id(pathId);
			id.setPath_ver(pathVer);
			Bis_pathi bis_pathi = bisPathiDao.get(id);
			if(bis_pathi !=null){
				if(bis_pathi.getPath_cate().equals(PATH_TYPE_REWK)){
					oary.setOqc_skip_flg(_YES);
				}else{
					oary.setOqc_skip_flg(_NO);
				}
			}
			oary.setBnk_flg(ret_prd_info.getBnk_flg());
			if (ret_prd_info.getPrd_stat().equals("INPR")) {
				oary.setCr_ope_id(ret_prd_info.getCr_ope_id_fk());
				oary.setCr_ope_no(ret_prd_info.getCr_ope_no_fk());
				oary.setCr_ope_ver(ret_prd_info.getCr_ope_ver_fk());
				oary.setCr_path_id(ret_prd_info.getCr_path_id_fk());
				oary.setCr_path_ver(ret_prd_info.getCr_path_ver_fk());
				oary.setCr_proc_id_fk(ret_prd_info.getCr_proc_id_fk());
			} else {
				oary.setCr_ope_id(ret_prd_info.getNx_ope_id_fk());
				oary.setCr_ope_no(ret_prd_info.getNx_ope_no_fk());
				oary.setCr_ope_ver(ret_prd_info.getNx_ope_ver_fk());
				oary.setCr_path_id(ret_prd_info.getNx_path_id_fk());
				oary.setCr_path_ver(ret_prd_info.getNx_path_ver_fk());
				oary.setCr_proc_id_fk(ret_prd_info.getNx_proc_id_fk());
			}
			oary.setTool_id_fk(ret_prd_info.getTool_id_fk());
			oary.setLot_id_fk(ret_prd_info.getLot_id());
			oary.setMdl_id_fk(ret_prd_info.getMdl_id_fk());
			oary.setSo_id_fk(ret_prd_info.getSo_id_fk());
			oary.setWo_id_fk(ret_prd_info.getWo_id_fk());
			oary.setMtrl_box_id(ret_prd_info.getMtrl_box_id_fk());
			oaryList.add(oary);
		}
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
		outTrx.setOary3(oaryList);
		outTrx.setOary3_cnt(oaryList.size());
    }
    
	private void summaryWoInfoFor9800() {
		String realSoId = inTrx.getSo_id();
		
		//time
		Timestamp zdfrom_date = inTrx.getZdfrom_date();
	    Timestamp zdto_date = inTrx.getZdto_date();
		Timestamp jlfrom_date = inTrx.getJlfrom_date();
		Timestamp jlto_date = inTrx.getJlto_date();
		Timestamp jjfrom_date = inTrx.getJjfrom_date();
		Timestamp jjto_date = inTrx.getJjto_date();
		//end

		String tmpSoId, woId, opeId, grade, boxId, prdStat, lotId, dnNo, bnkFlg;
		Map<StatBoxOpeBnkWoKey, Integer> rowMap = new HashMap<StatBoxOpeBnkWoKey, Integer>();//在制品
		Map<StatBoxOpeBnkWoKey, String> lotMap = new HashMap<StatBoxOpeBnkWoKey, String>();//批次号
		Map<String, String> dnMap = new HashMap<String, String>();//DN号
		Map<WoGradeKey, Integer> gradeMap = new HashMap<WoGradeKey, Integer>();//LZ,GK,NG品数量
		Map<String, Ret_wo> woMap = new HashMap<String, Ret_wo>();//实际订单所对应的所有内部订单Map
		Map<String, Ret_wo> soMap = new HashMap<String, Ret_wo>();//虚拟订单Map

		//sql
		hql = "FROM Ret_wo where wo_typ='S'";
		
		if(!realSoId.equals("")){
			hql += " AND so_id ='" + realSoId + "'";
		}
		if(zdfrom_date!=null){
			hql += " AND crt_timestamp >= '" + zdfrom_date + "'";
		}
		if(zdto_date!=null){
			hql += " AND crt_timestamp <= '" + zdto_date + "'";
		}
		if(jlfrom_date!=null){
			hql += " AND pln_stb_date >= '" + jlfrom_date + "'";
		}
		if(jlto_date!=null){
			hql += " AND pln_stb_date <= '" + jlto_date + "'";
		}
		if(jjfrom_date!=null){
			hql += " AND pln_cmp_date >= '" + jjfrom_date + "'";
		}
		if(jjto_date!=null){
			hql += " AND pln_cmp_date <= '" + jjto_date + "'";
		}

		//end
		List<Ret_wo> retSoList = retWODao.find(hql);
		if (retSoList.isEmpty()) {
			outTrx.setRtn_code("1");
			outTrx.setRtn_mesg("找不到生产订单信息:" + realSoId);
			return;
		}
		for (Ret_wo retSo : retSoList) {

			tmpSoId = retSo.getSo_id();
			soMap.put(tmpSoId, retSo);

			hql = "FROM Ret_wo where wo_typ='W' and so_id ='" + tmpSoId + "'";
			if(zdfrom_date!=null){
				hql += " AND crt_timestamp >= '" + zdfrom_date + "'";
			}
			if(zdto_date!=null){
				hql += " AND crt_timestamp <= '" + zdto_date + "'";
			}
			if(jlfrom_date!=null){
				hql += " AND pln_stb_date >= '" + jlfrom_date + "'";
			}
			if(jlto_date!=null){
				hql += " AND pln_stb_date <= '" + jlto_date + "'";
			}
			if(jjfrom_date!=null){
				hql += " AND pln_cmp_date >= '" + jjfrom_date + "'";
			}
			if(jjto_date!=null){
				hql += " AND pln_cmp_date <= '" + jjto_date + "'";
			}
			List<Ret_wo> retWoList = retWODao.find(hql);

			for (Ret_wo retWo : retWoList) {
				woMap.put(retWo.getWo_id(), retWo);
			}

			hql = "FROM Ret_prd_info where so_id_fk='" + tmpSoId + "'";
			List<Ret_prd_info> retPrdInfoList = retPrdInfoDao.find(hql);

			for (Ret_prd_info retPrdInfo : retPrdInfoList) {

				prdStat = retPrdInfo.getPrd_stat();
				boxId = retPrdInfo.getBox_id_fk();
				bnkFlg = retPrdInfo.getBnk_flg();
				woId = retPrdInfo.getWo_id_fk();
				opeId = "INPR".equals(prdStat) ? retPrdInfo.getCr_ope_id_fk() : retPrdInfo.getNx_ope_id_fk();

				//确定箱子数量,当状态为INPR且未转入玻璃时,只显示站点信息
				StatBoxOpeBnkWoKey rowKey = new StatBoxOpeBnkWoKey(prdStat, opeId, boxId, bnkFlg, woId);
				if (rowMap.containsKey(rowKey)) {
					rowMap.put(rowKey, rowMap.get(rowKey) + 1);
				} else {
					rowMap.put(rowKey, 1);
				}

				//获取批次号，若同一箱内的玻璃批次号有不同，显示为MIX
				lotId = retPrdInfo.getLot_id();
				if (lotId != null) {
					if (lotMap.containsKey(rowKey)) {
						if (!lotId.equals(lotMap.get(rowKey))) {
							lotMap.put(rowKey, "Mix");
						}
					} else {
						lotMap.put(rowKey, lotId);
					}
				}
				
				//统计DN号，若同一箱内的玻璃DN号相同
				dnNo = retPrdInfo.getDn_no();
				if (dnNo != null) {
					if (!dnMap.containsKey(boxId)) {
						dnMap.put(boxId, dnNo);
					}
				}


				//统计LZ,GK,NG品数量，单位暂定为生产订单(SO)
				grade = retPrdInfo.getPrd_grade();
				WoGradeKey gradeKey = new WoGradeKey(woId, grade);
				if (grade != null) {
					if (gradeMap.containsKey(grade)) {
						gradeMap.put(gradeKey, gradeMap.get(grade) + 1);
					} else {
						gradeMap.put(gradeKey, 1);
					}
				}

			}
		}

		Iterator<Entry<String, Ret_wo>> iter1 = woMap.entrySet().iterator();
		Iterator<Entry<StatBoxOpeBnkWoKey, Integer>> iter2 = rowMap.entrySet().iterator();
		List<XpinqsorO1> oary1List = new ArrayList<XpinqsorO1>();
		List<XpinqsorO2> oary2List = new ArrayList<XpinqsorO2>();
		Ret_wo retWo = null;
		//返回内部订单信息
		while (iter1.hasNext()) {
			XpinqsorO1 oary1 = new XpinqsorO1();
			Entry<String, Ret_wo> entry = iter1.next();
			retWo = entry.getValue();
			oary1.setCrt_usr(soMap.get(retWo.getSo_id()).getCrt_usr());
			oary1.setCrt_timestamp(soMap.get(retWo.getSo_id()).getCrt_timestamp());
			oary1.setPln_cmp_date(retWo.getPln_cmp_date());
			oary1.setPln_stb_date(retWo.getPln_stb_date());
			oary1.setMtrl_prod_id(retWo.getMtrl_prod_id_fk());

			/**
			 * 1.当一个订单有两个不同生产型号时，会拆分成两个不同的虚拟订单
			 *   这种情况发生时，订单总量为各自虚拟订单的总量(pln_prd_qty)
			 * 2.当一个内部订单只有一个生产型号时，且不知道具体的订单ID，需要临时创建一个.
			 *   这种情况发生时，只有一对一关系。(虚拟绑定实际)
			 */

			oary1.setSo_pln_prd_qty(fmtInt(soMap.get(retWo.getSo_id()).getPln_prd_qty()));
			oary1.setMdl_id(retWo.getMdl_id_fk());
			oary1.setFm_mdl_id(retWo.getFm_mdl_id_fk());
			oary1.setCut_mdl_id(retWo.getCut_mdl_id_fk());
			oary1.setWo_id(retWo.getWo_id());
			oary1.setSo_id(retWo.getSo_id());
			oary1.setWo_pln_prd_qty(retWo.getPln_prd_qty());
			oary1.setRecive_timestamp(retWo.getEvt_timestamp());
			oary1List.add(oary1);
		}

		StatBoxOpeBnkWoKey rowKey = null;
		while (iter2.hasNext()) {
			Entry<StatBoxOpeBnkWoKey, Integer> entry = iter2.next();
			rowKey = entry.getKey();
			prdStat = rowKey.getPrd_stat();
			boxId = rowKey.getBox_id();
			bnkFlg = rowKey.getBnk_flg();
			opeId = rowKey.getOpe_id();
			woId = rowKey.getWo_id();

			retWo = woMap.get(woId);
			if (null != retWo) {
				XpinqsorO2 oary2 = new XpinqsorO2();
				oary2.setWo_id(retWo.getWo_id());
				oary2.setDn_no(dnMap.get(boxId));
				oary2.setWo_pln_prd_qty(fmtInt(retWo.getPln_prd_qty()));
				oary2.setRl_prd_qty(fmtInt(retWo.getRl_prd_qty()));
				oary2.setUn_rl_prd_qty(fmtInt(retWo.getPln_prd_qty()) - fmtInt(retWo.getRl_prd_qty()));
				oary2.setComp_prd_qty(fmtInt(retWo.getComp_prd_qty())+ fmtInt(retWo.getWh_in_prd_qty())+ fmtInt(retWo.getWip_wh_in_prd_qty())+ fmtInt(retWo.getWh_out_prd_qty()));
				oary2.setUn_comp_prd_qty(fmtInt(retWo.getPln_prd_qty())-fmtInt(oary2.getComp_prd_qty()));
				oary2.setWh_out_prd_qty(fmtInt(retWo.getWh_out_prd_qty()));
				oary2.setUn_wh_out_prd_qty(fmtInt(retWo.getPln_prd_qty()) - fmtInt(retWo.getWh_out_prd_qty()));
				oary2.setGrade_gk_qty(fmtInt(gradeMap.get(new WoGradeKey(woId, "GK"))));
				oary2.setGrade_lz_qty(fmtInt(gradeMap.get(new WoGradeKey(woId, "LZ"))));
				oary2.setGrade_ng_qty(fmtInt(gradeMap.get(new WoGradeKey(woId, "NG"))));
				oary2.setLot_id(lotMap.get(rowKey));
				oary2.setBox_id(boxId);
				oary2.setOpe_id(opeId);
				oary2List.add(oary2);
			}
		}
		//返回内部订单数量信息

		outTrx.setOary1(oary1List);
		outTrx.setOary1_cnt(oary1List.size());
		outTrx.setOary2(oary2List);
		outTrx.setOary2_cnt(oary2List.size());
		outTrx.setRtn_code(RETURN_CODE_OK);
		outTrx.setRtn_mesg(RETURN_MESG_OK);
	}

	private Integer fmtInt(Integer val) {
		return val == null ? 0 : val;
	}
}
